package com.myk.game.gobangchess.ai.shock;

public class Winningtest {

    public static int[] winningtest(int[][] board) {
        int[] canWin = {0, 0};

        int[][][] convKernels = {
                {{1, 0, 0, 0},
                {0, 1, 0, 0},
                {0, 0, 1, 0},
                {0, 0, 0, 1}},
                {{0, 0, 0, 1},
                {0, 0, 1, 0},
                {0, 1, 0, 0},
                {1, 0, 0, 0}},
                {{1, 1, 1, 1}},
                {{1},
                {1},
                {1},
                {1}}
        };

        for (int kernelIdx = 0; kernelIdx < 4; kernelIdx++) {
            int[][] convResult = conv2(board, convKernels[kernelIdx]);
            if (hasAnyValueGreaterThanOrEqualTo(convResult, 3)) {
                canWin[0] = 1;
            }
            if (hasAnyValueLessThanOrEqualTo(convResult, -3)) {
                canWin[1] = 1;
            }
        }

        return canWin;
    }

    private static int[][] conv2(int[][] board, int[][] kernel) {
        int numRows = board.length;
        int numCols = board[0].length;
        int kernelRows = kernel.length;
        int kernelCols = kernel[0].length;
        int[][] result = new int[numRows - kernelRows + 1][numCols - kernelCols + 1];

        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                int sum = 0;
                for (int m = 0; m < kernelRows; m++) {
                    for (int n = 0; n < kernelCols; n++) {
                        sum += board[i + m][j + n] * kernel[m][n];
                    }
                }
                result[i][j] = sum;
            }
        }

        return result;
    }

    private static boolean hasAnyValueGreaterThanOrEqualTo(int[][] matrix, int threshold) {
        for (int[] row : matrix) {
            for (int value : row) {
                if (value >= threshold) {
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean hasAnyValueLessThanOrEqualTo(int[][] matrix, int threshold) {
        for (int[] row : matrix) {
            for (int value : row) {
                if (value <= threshold) {
                    return true;
                }
            }
        }
        return false;
    }
}
